'''
Created on Sep 20, 2009

@author: jafd
'''

import dialects

class Expression(object):
    """
    I represent a generic expression. I'm just a base so that
    other expressions are free to subclass me. All kinds of
    expressions must inherit me to be translated by a Dialect.
    
    I have mutated magic methods so that basic math operations
    return in fact Expressions and not the computed results --
    they are passed to a dialect to be translated to strings, and
    then they are passed to RDBMSes.
    """
    dialect = dialects.Dialect()
    EQUAL = "="
    NOTEQUAL = "!="
    LESSTHAN = "<"
    GREATERTHAN = ">"
    ADD = "+"
    SUBTRACT = "-"
    MULTIPLY = "*"
    DIVIDE = "/"
    LIKE = "LIKE"
    MOD = "MOD"

    def __init__(self):
        pass
    
    def __str__(self):
        return self.dialect.translate(self)
    
    def __add__(self, other):
        return BinaryExpression(self, other, self.ADD)
    
    def __radd__(self, other):
        return BinaryExpression(other, self, self.ADD)
    
    def __sub__(self, other):
        return BinaryExpression(self, other, self.SUBTRACT)
    
    def __rsub__(self, other):
        return BinaryExpression(other, self, self.SUBTRACT)
    
    def __mul__(self, other):
        return BinaryExpression(self, other, self.MULTIPLY)

    def __rmul__(self, other):
        return BinaryExpression(other, self, self.MULTIPLY)
    
    def __div__(self, other):
        return BinaryExpression(self, other, self.DIVIDE)

    def __rdiv__(self, other):
        return BinaryExpression(other, self, self.DIVIDE)

    def __mod__(self, other):
        return BinaryExpression(self, other, self.MOD)

    def __rmod__(self, other):
        return BinaryExpression(other, self, self.DIVIDE)

    
class UnaryExpression(Expression):
    operation = None
    value = None
    def __init__(self, op, value):
        self.operation = op
        self.value = value
        
class ExpressionGroup(UnaryExpression):
    def __init__(self, value):
        UnaryExpression.__init__(self, None, value)
        
class Function(UnaryExpression):
    def __init__(self, op, value=None):
        self.operation = op
        if isinstance(value, ExpressionGroup):
            self.value = value
        elif isinstance(value, Expression):
            self.value = ExpressionGroup(value)
        elif value == None:
            self.value = ExpressionGroup(None)
        else:
            self.value = ExpressionGroup(Literal(value))

class Literal(UnaryExpression):
    def __init__(self, value):
        UnaryExpression.__init__(self, None, value)
        
class AttributeName(UnaryExpression):
    def __init__(self, *args):
        UnaryExpression.__init__(self, None, args)

class BinaryExpression(Expression):
    lvalue = None
    rvalue = None
    operation = None
    
    def __init__(self, lvalue, rvalue, operation):
        self.operation = operation
        self.lvalue = lvalue
        self.rvalue = rvalue

class Comparison(BinaryExpression):
    pass

class Assignment(BinaryExpression):
    pass

class ExpressionList(Expression):
    def __init__(self, *args):
        self.value = args
        
